<template>
  <div id="all-div" class="data-view">
    <!-- 数据列表  算子列表   -->
    <div
      v-show="isPanelShow"
      class="panel"
      :style="{ width: `${menuCurrentWidth}px` }"
    >
      <data-list
        :project-id="projectId"
        :mode="isVisitor || isLock"
        @add-data="addData"
        @drag-position="dragPosition"
      />
      <operator-list
        v-if="!isVisitor && !isLock"
        class="operator-list-cont"
        :project-id="projectId"
        :pipeline-id="activePipelineId"
        :is-lock="isLock"
        @add-operator="addOperator"
        @drag-position="dragPosition"
      />
    </div>

    <div id="dataview-menu-resize-line" class="dataview-menu-resize-line" />

    <div
      class="model-content"
      :style="{ width: `calc(100% - ${isPanelShow ? 180 : 0}px)` }"
    >
      <!-- <div class="model-content" > -->
      <tabs
        v-if="tabs.length > 1"
        ref="tab"
        v-model="activePipelineId"
        :min-hidden-width="120"
        :tabs="tabs"
        :allowed-edit="false"
        :allowed-delete="false"
        @check="changePipelineId"
      >
      </tabs>

      <!-- 功能按钮  -->
      <div v-if="!panelFullScreen" class="function-btn">
        <pipeline-function
          @pipeline-run="pipelineRunning"
          @pipeline-stop="pipelineStop"
          @toggle-log="toggleRunLog"
          @toggle-favorite="toggleFavorite"
          @toggle-screenshot="toggleScreenshot"
          @toggle-history="toggleHistory"
          @over-save="saveShot"
        />
      </div>

      <div
        ref="pipelineAndEdit"
        class="graph-content-node"
        :class="tabs.length > 1 ? 'with-tab' : 'no-tab'"
      >
        <!-- 画布   -->
        <div
          id="id-graph"
          class="graph-content"
          :style="{ height: `calc(100% - ${moduleOfNodeEditHeight}px)` }"
        >
          <!-- 管道画布 -->
          <pipeline
            ref="graph"
            :project-id="projectId"
            :pipeline-id="activePipelineId"
            @close-log="logStatus = false"
            @close-favorite="favoriteStatus = false"
            @close-history="historyStatus = false"
            @close-shot="saveShotShow = false"
          />
        </div>
        <!--   节点编辑模块  -->
        <div
          ref="node-edit-box"
          class="node-edit-module"
          :style="{
            height: moduleOfNodeEditHeight + 'px',
            transition: `all ${isNodeEditModuleDragged ? 0 : transitionTime}s`,
          }"
        >
          <!-- 拖拽 -->
          <!--          <a-button-->
          <!--            type="primary"-->
          <!--            class="fullScreen-button"-->
          <!--            title="全屏"-->
          <!--            :style="{ right: isShowVisualization ? '250px' : '50px' }"-->
          <!--            @click="fullScreen"-->
          <!--          >-->
          <!--            <a-icon-font-->
          <!--              :type="-->
          <!--                panelFullScreen-->
          <!--                  ? 'icontuichuquanping'-->
          <!--                  : 'iconfangdahuabanquanping'-->
          <!--              "-->
          <!--            />-->
          <!--          </a-button>-->
          <node-edit-panel
            ref="node-edit-panel"
            :panel-full-screen="panelFullScreen"
            @toggle-full-screen="fullScreen"
          />
          <div
            v-if="!panelFullScreen"
            class="resize-edit-panel-height"
            @mousedown="resizeLogHeight($event)"
          ></div>
        </div>

        <!-- 日志 -->
        <div class="run-log" :style="{ width: logStatus ? '420px' : 0 }">
          <run-log @log-close="toggleRunLog" />
        </div>
        <!-- 可视化收藏 -->
        <div
          v-show="favoriteStatus"
          class="run-log"
          :style="{ width: favoriteStatus ? '360px' : 0 }"
        >
          <data-visualization
            :pipeline-id="activePipelineId"
            @favorite-close="toggleFavorite"
          />
        </div>
        <!-- 版本历史 -->
        <div
          v-show="historyStatus"
          class="run-log"
          :style="{ width: historyStatus ? '444px' : 0 }"
        >
          <pipeline-history
            ref="history"
            :history-refresh="historyRefresh"
            @history-close="toggleHistory"
          />
        </div>
      </div>
    </div>

    <div
      v-show="saveShotShow"
      class="save-shot"
      :style="{ top: tabs.length > 1 ? '76px' : '40px' }"
    >
      <strong>保存当前版本</strong>
      <div class="input-div">
        <span>命名为：</span>
        <a-input v-model="shotName" placeholder="请输入"></a-input>
      </div>
      <div class="btn-div" align="right">
        <a-button
          size="small"
          style="margin-right: 10px;"
          @click="
            saveShotShow = false
            shotName = ''
          "
          >取消
        </a-button>
        <a-button size="small" type="primary" @click="clickGeneratePicture"
          >确定
        </a-button>
      </div>
    </div>

    <!-- 可视化推荐 -->
    <VisualRecommendation
      v-if="enableVRPanelRecommend"
      :is-with-tab="tabs.length > 1 ? true : false"
    ></VisualRecommendation>

    <!-- 智能推荐开关  -->
    <div
      v-if="!panelFullScreen"
      class="intelligent-btn"
      :class="tabs.length > 1 ? 'with-tab' : 'no-tab'"
    >
      <intelligent-recommendation />
    </div>

    <!-- 可视化对比 header -->
    <comparison-header :style="{ height: comparisonStatus ? '64px' : 0 }" />
  </div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import ProjectStore, { Project } from '@/store/modules/project'
import DataList from '@/components/studio/data/panel/DataList.vue'
import OperatorList from '@/components/studio/data/panel/OperatorList.vue'
import Pipeline from '@/components/studio/data/Pipeline.vue'
import VisualComparison from '@/components/studio/data/popup/VisualComparison.vue'
import {
  addPipeline,
  pipelineList,
  saveSnapshot,
  checkSnapshotThreshold,
  querySnapshot,
} from '@/api/pipeline'
import domtoimage from 'dom-to-image'
import Tabs from '@/components/studio/data/graph-compoments/Tabs.vue'
import DataViewStore from '@/store/modules/dataview'
import NodeEditPanel from '@/components/studio/data/node-edit-panel/NodeEditPanel.vue'
import RunLog from '@/components/studio/data/RunLog.vue'
import PipelineHistory from '@/components/studio/data/PipelineHistory.vue'
import DataVisualization from '@/components/studio/data/node-edit-panel/DataVisualization.vue'
import ComparisonHeader from '@/components/studio/data/ComparisonHeader.vue'
import PipelineFunction from '@/components/studio/data/PipelineFunction.vue'
import IntelligentRecommendation from '@/components/studio/data/IntelligentRecommendation.vue'
import VisualRecommendation from './VisualRecommendation.vue'

// @ts-ignore
const elementResizeDetectorMaker = require('element-resize-detector')

@Component({
  components: {
    DataList,
    OperatorList,
    Pipeline,
    VisualComparison,
    NodeEditPanel,
    RunLog,
    DataVisualization,
    ComparisonHeader,
    VisualRecommendation,
    PipelineFunction,
    IntelligentRecommendation,
    Tabs,
    PipelineHistory,
  },
  directives: {
    focus: {
      inserted: (element: any) => {
        element.focus()
      },
    },
  },
})
export default class DataView extends Vue {
  public tabs: any[] = [
    //  {id: 756, name: 'new pip2', projectId: 233, userId: 53, data: {name: 'test'}},
  ]
  // 日志状态
  public logStatus: boolean = false
  // 可视化收藏状态
  public favoriteStatus: boolean = false
  // 版本快照历史状态
  public historyStatus: boolean = false
  // 版本快照历史刷新
  public historyRefresh: boolean = false
  // 保存快照弹窗
  public saveShotShow: boolean = false
  // 快照命名
  public shotName: string | null = null
  // 快照url
  public shotUrl: string = ''
  // 当前 pipeline id
  public activePipelineId: number | null = null
  // 当前 项目 Id
  public projectId: number | null = null
  // 日志高度
  public moduleOfNodeEditHeight = 0

  public mouseLastPosition = { x: 0, y: 0 }
  // 节点编辑面板放大(只充满建议左边的部分)
  public panelFullScreen: boolean = false
  // 全屏高度
  public fullScreenHeight = -1
  // 全屏前节点编辑高度
  public panelPreHeight = -1
  // 节点编辑面板是否在拖动改变高度
  public isNodeEditModuleDragged: boolean = false
  // 节点编辑面板动画时间
  public transitionTime: number = 0

  public keyCode1: number | null = null
  public keyCode2: number | null = null
  public keyCode3: number | null = null

  // store 中的选择的节点
  public get selectNode(): any {
    return DataViewStore.selectNode
  }

  public get isVisitor() {
    return DataViewStore.isVisitor
  }

  public get isLock() {
    return DataViewStore.getLock
  }

  public get project(): Project | null {
    return ProjectStore.activeProject
  }

  public get actionArea() {
    return DataViewStore.ActionArea
  }

  @Watch('selectNode')
  public changeNode(node: any) {
    this.transitionTime = 0
    if (node && +node.type !== 6) {
      // 图构建节点不触发
      this.moduleOfNodeEditHeight = DataViewStore.nodeEditPanelHeight
      const { isSample } = node.data || {} // 是否采样任务
      if (['CREATE', 'RUNNING'].includes(isSample)) {
        // 采样任务运行时，点开节点进行提示
        this.$message.info('当前为采样数据，全量任务后台运行中，请稍候', 4)
      }
      this.$nextTick(() => {
        const targetElement = this.$el.querySelector('.node-selected')
        targetElement?.scrollIntoView() // 控制选中的节点滚动到可视区域
      })
    } else {
      this.moduleOfNodeEditHeight = 0
    }
    this.$nextTick(() => {
      const reference: any = this.$refs.graph as Vue
      reference.initVariable()
    })
  }

  @Watch('saveShotShow')
  public saveShotShowChange() {
    if (this.saveShotShow === true) {
      this.historyStatus = false
      this.favoriteStatus = false
      this.logStatus = false
      DataViewStore.setSelectFunctionIndex(2)
    } else {
      DataViewStore.setSelectFunctionIndex(null)
    }
  }

  @Watch('historyStatus')
  public historyStatusChange() {
    DataViewStore.setHistoryStatus(this.historyStatus)
    if (this.historyStatus === true) {
      DataViewStore.setSelectFunctionIndex(null)
    }
  }

  @Watch('favoriteStatus')
  public favoriteStatusChange() {
    DataViewStore.setFavoriteStatus(this.favoriteStatus)
    if (this.favoriteStatus === true) {
      DataViewStore.setSelectFunctionIndex(null)
    }
  }

  @Watch('logStatus')
  public logStatusChange() {
    if (this.logStatus === true) {
      DataViewStore.setSelectFunctionIndex(4)
    } else {
      DataViewStore.setSelectFunctionIndex(null)
    }
  }

  /**
   * 沿用 版本1 pipeline list 存在
   */
  public beforeMount() {
    this.getPipelineList()
  }

  public created() {
    // 当前 项目 Id
    this.projectId = Number(this.$route.params.id)
    DataViewStore.setProjectId(this.projectId)
  }

  public mounted() {
    this.initViewEvent()
    const reference: any = this.$refs.graph as Vue
    // this.setDataCleanTableHeight()

    DataViewStore.setSidePanel(true)
    DataViewStore.setNodeEditPanelIsFullScreen(false)
    const self = this
    const erd = elementResizeDetectorMaker()
    const graph = document.querySelector('#id-graph') as HTMLElement
    erd.listenTo(graph, () => {
      self.$nextTick(() => {
        // 监听到事件后执行的业务逻辑
        reference.initVariable()
      })
    })
    // 改为实时监听模式，避免表格高度不同步的情况
    this.$nextTick(() => {
      const erdTable = elementResizeDetectorMaker()

      const nodeEditBox = this.$refs['node-edit-box'] as HTMLElement

      erdTable.listenTo(nodeEditBox, function (element: HTMLElement) {
        DataViewStore.setTableHeight(element.offsetHeight - 38 - 270 - 5)
      })
      this.$once('hook:beforeDestroy', () => {
        erd.removeAllListeners(graph)
        erdTable.removeAllListeners(nodeEditBox)
      })
    })

    document.addEventListener('keyup', this.globalKeyUp)
    document.addEventListener('keydown', this.globalKeyDown)

    if (sessionStorage.getItem('lastUrl')) {
      sessionStorage.removeItem('lastUrl')
      // 调用添加数据到项目的接口
    }
  }

  public beforeDestroy() {
    document.removeEventListener('keyup', this.globalKeyUp)
    document.removeEventListener('keydown', this.globalKeyDown)
    if (this.panelFullScreen) {
      //  全屏模式下离开dataView 重设panel Height 为默认值400
      DataViewStore.setNodeEditPanelHeight(400)
    }
  }

  // 菜单相关参数
  private menuMaxWidth = 350 // 最大宽度
  private menuMinWidth = 175 // 最小宽度
  private menuCurrentWidth = 190 // 当前宽度

  // 初始化resize事件
  public initViewEvent() {
    const resizeBar = document.querySelector(
      '#dataview-menu-resize-line'
    ) as any

    // 鼠标按下事件
    const mouseDownEvent = ($event: any) => {
      const initCurrentWidth = this.menuCurrentWidth
      const startX = $event.clientX
      const mouseMoveEvent: any = (event: any) => {
        const endX = event.clientX
        const moveLength = endX - startX
        let newWidth = initCurrentWidth + moveLength
        if (newWidth > this.menuMaxWidth) {
          newWidth = this.menuMaxWidth
        } else if (newWidth < this.menuMinWidth) {
          newWidth = this.menuMinWidth
        }
        this.menuCurrentWidth = newWidth
        this.$forceUpdate()
      }
      document.addEventListener('mousemove', mouseMoveEvent)
      const mouseUpEvent: any = () => {
        document.removeEventListener('mousemove', mouseMoveEvent)
        document.removeEventListener('mouseup', mouseUpEvent)
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        resizeBar.releaseCapture && resizeBar.releaseCapture()
      }
      document.addEventListener('mouseup', mouseUpEvent)
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      resizeBar.setCapture && resizeBar.setCapture()
      return false
    }
    resizeBar.addEventListener('mousedown', mouseDownEvent)
    this.$once('hook:beforeDestroy', () => {
      resizeBar.removeEventListener('mousedown', mouseDownEvent)
    })
  }

  public globalKeyDown($event: KeyboardEvent) {
    if (this.isVisitor || this.isLock) {
      return
    }
    if (this.actionArea === 'pipeline') {
      if ($event.key === 'Control' || $event.key === 'Meta') {
        this.keyCode1 = 1
      }
      if ($event.key === 's' || $event.key === 'S') {
        this.keyCode2 = 2
      }
      if ($event.key === 'Shift') {
        this.keyCode3 = 3
      }
    }
    if (this.keyCode1 === 1 && this.keyCode2 === 2 && this.keyCode3 === 3) {
      this.toggleScreenshot()
    }
  }

  public globalKeyUp($event: KeyboardEvent) {
    if (this.isVisitor || this.isLock) {
      return
    }
    if (this.actionArea === 'pipeline') {
      if ($event.key === 'Control' || $event.key === 'Meta') {
        this.keyCode1 = null
        this.keyCode2 = null
      }
      if ($event.key === 's' || $event.key === 'S') {
        this.keyCode2 = null
      }
      if ($event.key === 'Shift') {
        this.keyCode2 = null
        this.keyCode3 = null
      }
    }
  }

  // 切换用户pipeline
  public changePipelineId(pipelineId: number) {
    this.activePipelineId = pipelineId
    DataViewStore.setPipelineId(this.activePipelineId)
    DataViewStore.setLocateNodes([])
    // 关闭pipeline所有打开面板
    const reference: any = this.$refs.graph as Vue
    reference.closeAll()
    const userTab = this.tabs.find((item) => {
      return this.activePipelineId === item.id
    })
    DataViewStore.setTabName(userTab?.data.key)
  }

  // 截取屏幕快照
  public clickGeneratePicture() {
    if (!this.shotName) {
      this.$message.error('版本快照命名不能为空！')
      return
    }

    const graph = document.querySelector('#global-graph') as HTMLElement
    const cloneNode = document.createElement('div')
    cloneNode.innerHTML = graph?.outerHTML
    cloneNode.style.display = 'none'
    graph?.parentNode?.insertBefore(cloneNode, graph) // 将cloneNode插入到graph之前
    const svgElement = cloneNode.querySelectorAll('svg')

    svgElement.forEach((svg) => {
      const child = svg.firstChild as HTMLElement
      if (child.tagName === 'use') {
        const svgId = child?.getAttribute('xlink:href') // ?.replace(/#/,'')?? ''

        if (svgId !== null) {
          const svgContent = document.querySelector(svgId) as HTMLElement
          svg.innerHTML = svgContent?.innerHTML

          if (svgContent) {
            svg.innerHTML = svgContent.innerHTML
            const viewBoxString =
              svgContent.getAttribute('viewBox') ?? '0 0 1024 1024'
            svg.setAttribute('viewBox', viewBoxString)
          }
        }
      }
    })
    cloneNode.style.display = 'block'
    graph.style.display = 'none'

    const that = this
    domtoimage.toPng(cloneNode).then(function (dataUrl: string) {
      graph.style.display = 'block'
      graph.parentNode?.removeChild(cloneNode)
      that.shotUrl = dataUrl
      // check阈值
      checkSnapshotThreshold({
        data: {
          pipelineId: that.activePipelineId,
          projectId: that.projectId,
          pipelineSnapshotName: that.shotName,
        },
      })?.then((response: any) => {
        if (response.data.code === 100 && response.data.tips) {
          // 储存库满
          that.saveShotShow = false
          DataViewStore.setOverSaveVisible(true)
        } else {
          that.saveShot()
        }
      })
    })
  }

  // base64转file
  public dataURLtoBlob(dataurl: string) {
    const array = dataurl.split(',')
    const mime = array[0].match(/:(.*?);/) ?? []
    const bstr = atob(array[1])
    let n = bstr.length
    const u8array = new Uint8Array(n)
    while (n > 0) {
      n -= 1
      u8array[n] = bstr.charCodeAt(n)
    }
    return new Blob([u8array], { type: mime[1] })
  }

  // 上传快照
  public async saveShot() {
    const formData = new FormData()
    formData.append('pipelineId', this.activePipelineId?.toString() || '')
    formData.append('projectId', this.projectId?.toString() || '')
    formData.append('pipelineSnapshotName', this.shotName?.toString() || '')
    formData.append('picture', this.dataURLtoBlob(this.shotUrl))
    const response = await saveSnapshot({
      data: formData,
    })

    if (response.data.code === 100) {
      this.$message.success('快照保存成功！', 3)
      this.saveShotShow = false
      const reference: any = this.$refs.history as Vue
      reference.querySnapshot()
      // this.historyRefresh = true
    } else {
      this.$message.error(response.data.message, 3)
    }
  }

  /**
   * 添加数据节点
   * @param data {dropped: data ,event: $event}
   */
  public addData(data: any) {
    const reference: any = this.$refs.graph as Vue
    reference.addData(data)
  }

  /**
   * 拖拽节点 落点
   * @param dragInfo {node, event}
   */
  private dragPosition(dragInfo: any) {
    const reference: any = this.$refs.graph as Vue
    reference.dragToNode(dragInfo)
  }

  /**
   * 添加算子节点
   * @param operator  {dropped: operator ,event: $event}
   */
  public addOperator(operator: any) {
    const reference: any = this.$refs.graph
    reference.addOperator(operator)
  }

  /**
   * 获取 pipeline 列表
   */
  public async getPipelineList() {
    const parameters = {
      projectId: this.projectId,
    }

    pipelineList({ data: parameters })?.then((response: any) => {
      if (response.data.code === 100) {
        const panes = response.data.result
        panes.forEach((element: { data: { key: any }; userName: any }) => {
          element.data.key = element.userName
        })
        if (DataViewStore && DataViewStore?.userRole?.id !== 4) {
          panes[0].userName = '我'
        }
        this.tabs = panes
        if (panes.length > 0) {
          this.activePipelineId = panes[0].id
          DataViewStore.setPipelineId(this.activePipelineId)
          DataViewStore.setTabName(panes[0].data.key)
        } else {
          // 默认创建一个pipeline
          this.addPipelineToProject()
        }
      }
    })
  }

  /**
   * 新建 pipeline
   */
  public async addPipelineToProject() {
    const newName = 'New Tab'
    const parameters = {
      name: newName,
      projectId: this.projectId,
      data: {
        key: 'value',
      },
    }
    addPipeline({ data: parameters })?.then((response: any) => {
      if (response.data.code === 100) {
        setTimeout(() => {
          this.activePipelineId = response.data.result
          DataViewStore.setPipelineId(this.activePipelineId)
        }, 50)
      }
    })
  }

  /**
   * pipeline 执行
   */
  public pipelineRunning() {
    const reference: any = this.$refs.graph as Vue
    reference.runPipeline()
  }

  /**
   * pipeline 停止
   */
  public pipelineStop() {
    const reference: any = this.$refs.graph as Vue
    reference.stopPipeline()
  }

  /**
   * 日志窗口 开关
   */
  public toggleRunLog() {
    this.historyStatus = false
    this.favoriteStatus = false
    this.saveShotShow = false
    this.logStatus = !this.logStatus
    // this.logStatus = true// !this.logStatus
  }

  /**
   * 收藏窗口 开关
   */
  public toggleFavorite() {
    this.historyStatus = false
    this.logStatus = false
    this.saveShotShow = false
    this.favoriteStatus = !this.favoriteStatus
  }

  /**
   * 保存当前版本
   */
  public async toggleScreenshot() {
    // 命名规则：projectName_1
    const response = await querySnapshot({
      data: {
        pipelineId: this.activePipelineId,
        projectId: this.projectId,
      },
    })
    const shotArray = response.data?.result ?? []
    // const shotArray = [{pipelineSnapshotName:'join03'},{pipelineSnapshotName:'join01'},{pipelineSnapshotName:'sssss'},{pipelineSnapshotName:'join04'},{pipelineSnapshotName:'join02'}]
    const name = this.project ? `${this.project.name}_` : ''
    const array: number[] = []
    shotArray.forEach((item: { pipelineSnapshotName: string }) => {
      if (item.pipelineSnapshotName.search(name) !== -1) {
        const vision = Number.parseInt(
          item.pipelineSnapshotName.replaceAll(name, ''),
          10
        )
        if (
          vision.toString() === item.pipelineSnapshotName.replaceAll(name, '')
        ) {
          array.push(vision)
        }
      }
    })
    const sortArray = array.sort((a: number, b: number) => a - b)
    if (sortArray.length === 0) {
      this.shotName = `${name}1`
    } else if (sortArray.length > 1) {
      for (let i = 0; i < sortArray.length - 1; i += 1) {
        if (sortArray[i + 1] - sortArray[i] > 1) {
          this.shotName = name + (sortArray[i] + 1)
          break
        } else {
          this.shotName = name + (sortArray[i + 1] + 1)
        }
      }
    } else {
      this.shotName = name + (sortArray[0] > 1 ? 1 : sortArray[0] + 1)
    }

    this.saveShotShow = true
  }

  /**
   * 快照历史版本 开关
   */
  public toggleHistory() {
    this.favoriteStatus = false
    this.logStatus = false
    this.saveShotShow = false
    this.historyStatus = !this.historyStatus
    // this.historyStatus = true// !this.historyStatus
  }

  private get comparisonStatus() {
    return DataViewStore.comparisonStatus
  }

  /**
   * 改变节点编辑模块高度
   */
  public resizeLogHeight($event: MouseEvent) {
    if (!this.panelFullScreen) {
      $event.stopPropagation()
      this.editPanelMaxHeight = (this.$refs
        .pipelineAndEdit as HTMLElement).getBoundingClientRect().height
      this.mouseLastPosition = { x: $event.screenX, y: $event.screenY }
      this.isNodeEditModuleDragged = true
      document.addEventListener('mouseup', this.dragMouseUpListener)
      document.addEventListener('mousemove', this.dragMouseMoveListener)
    }
  }

  private editPanelMaxHeight: number = 0 // 节点清洗编辑模块最大高度

  public dragMouseMoveListener({ screenX, screenY }: MouseEvent) {
    const dy = screenY - this.mouseLastPosition.y
    this.$nextTick(() => {
      if (
        this.moduleOfNodeEditHeight >= 38 &&
        this.moduleOfNodeEditHeight <= this.editPanelMaxHeight
      ) {
        let height: number = this.moduleOfNodeEditHeight - dy
        if (height < 38) {
          height = 38
        }
        if (height > this.editPanelMaxHeight) {
          height = this.editPanelMaxHeight
        }
        this.moduleOfNodeEditHeight = height
        this.mouseLastPosition = { x: screenX, y: screenY }
      }
    })
  }

  public async dragMouseUpListener() {
    const reference: any = this.$refs.graph as Vue
    reference.initVariable()
    document.removeEventListener('mousemove', this.dragMouseMoveListener)
    document.removeEventListener('mouseup', this.dragMouseUpListener)
    // 保存高度
    DataViewStore.setNodeEditPanelHeight(this.moduleOfNodeEditHeight)
    // this.setDataCleanTableHeight()
    this.isNodeEditModuleDragged = false
  }

  /**
   * 设置明细表格高度
   */
  // public setDataCleanTableHeight() {
  //   this.$nextTick(()=>{
  //     if(DataViewStore.dataTableInstance && isFunction(DataViewStore.dataTableInstance.checkHeight)){
  //       DataViewStore.dataTableInstance.checkHeight()
  //     }
  //   })
  // }

  /**
   * 设置数据源算子面板的展开和收缩
   */
  public get isPanelShow() {
    return DataViewStore.isSidePanelShow
  }

  /**
   * 是否启用智能推荐功能
   */
  public get enableVRPanelRecommend() {
    return DataViewStore.enableVRPanelRecommend
  }

  /**
   * 节点编辑面板全屏功能实现
   */
  public fullScreen() {
    if (this.fullScreenHeight === -1) {
      const dataView = document.querySelector('.data-view')
      if (dataView) {
        this.fullScreenHeight = dataView?.clientHeight
      }
    }
    if (this.transitionTime === 0) {
      this.transitionTime = 0.3
    }
    this.panelFullScreen = !this.panelFullScreen
    // 左右放缩
    DataViewStore.setSidePanel(!this.panelFullScreen)
    DataViewStore.setSideMenu(!this.panelFullScreen)

    // 上下放缩
    if (this.panelFullScreen) {
      this.panelPreHeight = this.moduleOfNodeEditHeight
      this.moduleOfNodeEditHeight = this.fullScreenHeight
    } else {
      this.moduleOfNodeEditHeight = this.panelPreHeight
    }

    // 更新数据
    DataViewStore.setNodeEditPanelHeight(this.moduleOfNodeEditHeight)
    // this.setDataCleanTableHeight()

    DataViewStore.setNodeEditPanelIsFullScreen(this.panelFullScreen)
  }

  /**
   * 设置数据源算子面板的展开和收缩
   */
  public get isShowVisualization() {
    return DataViewStore.nodeEditPanelIsShowVisualization
  }
}
</script>

<style lang="less" scoped>
@import '@/constants';
/* 数据视图 */
.data-view {
  background-color: #eff0f7;
  display: flex;
  height: calc(100vh - @HEADER_HEIGHT);
  position: relative;
  width: calc(100% - 160px);
}

/* 数据源 算子库 */
.panel {
  background-color: #fff;
  border-right: 1px solid #e6e6e6;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
  padding: 0 8px;
}

// 改变菜单宽度的线
.dataview-menu-resize-line {
  background-color: transparent;
  cursor: col-resize;
  height: 100%;
  left: -3px;
  position: relative;
  width: 5px;
}

/* 智能推荐开关 */
.intelligent-btn {
  float: right;
  width: 36px;

  &.with-tab {
    height: calc(100% - 38px);
    margin-top: 38px;
  }

  &.no-tab {
    height: 100%;
  }
}

/* 内容 */
.model-content {
  background-color: #ededf4;
  overflow: hidden;

  /* 功能按钮 */
  .function-btn {
    top: 38px;
    width: 100%;
  }

  /* 右侧 pipeline 和 节点编辑控件 */

  .graph-content-node {
    display: flex;
    flex: 1 1;
    flex-direction: column;
    justify-content: space-between;
    position: relative;
    width: 100%;

    &.with-tab {
      height: calc(100% - 76px);
    }

    &.no-tab {
      height: calc(100% - 36px);
    }

    /* 画布 */

    .graph-content {
      background-color: #fff;
      overflow: hidden;
      /*transition: height 0.3s;*/
    }

    /* 节点编辑模块 */

    .node-edit-module {
      position: relative;
      user-select: none;
      width: 100%;

      /* 改变节点编辑模块高度 */

      .resize-edit-panel-height {
        border-color: transparent;
        height: 10px;
        position: absolute;
        top: 0;
        width: 100%;

        &:hover {
          cursor: ns-resize;
        }
      }
    }

    /* 日志 */

    .run-log {
      background-color: #fff;
      height: 100%;
      position: absolute;
      right: 0;
      transition: width 0.3s;
      z-index: 350;
    }
  }
}

/* 对比弹窗 */
/deep/ .ant-modal-body {
  padding: 0;
}

/* 保存快照弹窗 */
.save-shot {
  background-color: #fff;
  border-radius: 2px;
  box-shadow: 0 0 4px 0 rgba(88, 98, 230, 0.2);
  padding: 10px;
  position: absolute;
  right: 42px;
  width: 242px;
  z-index: 351;

  b {
    font-size: 14px;
  }

  span {
    width: 80px;
  }

  .input-div {
    align-items: center;
    display: flex;
    margin-top: 10px;
  }

  .btn-div {
    margin-top: 10px;
    width: 100%;
  }
}

//.fullScreen-button {
//  background-color: #eff0f7;
//  border-color: #eff0f7;
//  box-shadow: none;
//  color: #666;
//  font-size: 16px;
//  height: 20px;
//  line-height: 20px;
//  margin-left: 24px;
//  opacity: 0.8;
//  padding: 0 4px;
//  position: absolute;
//  top: 10px;
//  width: 22px;
//  z-index: 9;
//
//  &:hover {
//    opacity: 1;
//  }
//}

.card-container {
  overflow: hidden;
  width: calc(100% - 180px);
}
</style>
